package com.fate.system.controller;

import com.fate.framework.exception.KKException;
import com.fate.framework.utils.CommonUtil;
import com.fate.system.constant.QuartzJobConst;
import com.fate.system.service.IDictService;
import com.fate.system.service.IQuartzJobService;
import com.fate.system.dto.quartzjob.QuartzJobAddDTO;
import com.fate.system.vo.quartzjob.QuartzJobListVO;
import com.fate.system.vo.quartzjob.QuartzJobDetailVO;
import com.fate.system.dto.quartzjob.QuartzJobUpdateDTO;
import com.fate.system.entity.QuartzJob;

import com.fate.framework.dto.IdParamDTO;
import com.fate.framework.utils.SystemUtil;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import com.fate.system.dto.quartzjob.QuartzJobPageDTO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.List;

@Slf4j
@Tag(name = "任务调度操作 API")
@RestController
@RequestMapping("/api/v1.0/quartzJob")
public class QuartzJobController {

  @Resource private IQuartzJobService quartzJobService;
  @Resource private Scheduler scheduler;
  @Resource private IDictService dictService;

  @Operation(summary = "新增")
  @PostMapping("/add")
  public void add(@RequestBody @Valid QuartzJobAddDTO addDTO) {
    QuartzJob quartzJob = SystemUtil.buildResource(addDTO, QuartzJob.class);

    List<QuartzJob> list =
        quartzJobService
            .lambdaQuery()
            .eq(QuartzJob::getJobClassName, quartzJob.getJobClassName())
            .list();
    if (CommonUtil.notNullOrEmpty(list)) {
      throw new KKException("该定时任务已经存在");
    }
    quartzJobService.saveAndScheduleJob(quartzJob);
  }

  @Operation(summary = "删除")
  @PostMapping("/remove")
  public void remove(@RequestBody @Valid IdParamDTO idParamDTO) {
    QuartzJob quartzJob = quartzJobService.getById(idParamDTO.getId());
    if (CommonUtil.isNullOrEmpty(quartzJob)) {
      throw new KKException("该定时任务不存在");
    }
    quartzJobService.deleteAndStopJob(quartzJob);
  }

  @Operation(summary = "更新")
  @PostMapping("/update")
  public void update(@RequestBody @Valid QuartzJobUpdateDTO updateDTO) {
    QuartzJob quartzJob = SystemUtil.buildResource(updateDTO, QuartzJob.class);
    try {
      quartzJobService.editAndScheduleJob(quartzJob);
    } catch (SchedulerException e) {
      log.error(e.getMessage(), e);
      throw new KKException("更新定时任务失败!");
    }
  }

  @Operation(summary = "详情")
  @PostMapping("/detail")
  public QuartzJobDetailVO detail(@RequestBody @Valid IdParamDTO idParamDTO) {
    QuartzJob quartzJob = quartzJobService.getById(idParamDTO.getId());
    return SystemUtil.buildResource(quartzJob, QuartzJobDetailVO.class);
  }

  @Operation(summary = "暂停定时任务")
  @GetMapping(value = "/pause")
  public void pauseJob(String jobClassName) {
    QuartzJob job;
    try {
      job = quartzJobService.lambdaQuery().eq(QuartzJob::getJobClassName, jobClassName).one();
      if (CommonUtil.isNullOrEmpty(job)) {
        throw new KKException("定时任务不存在");
      }
      scheduler.pauseJob(JobKey.jobKey(jobClassName.trim()));
    } catch (SchedulerException e) {
      throw new KKException("暂停定时任务失败");
    }
    job.setStatus(QuartzJobConst.STATUS_DISABLE);
    quartzJobService.updateById(job);
  }

  @Operation(summary = "恢复定时任务")
  @GetMapping(value = "/resume")
  public void resumeJob(String jobClassName) {
    QuartzJob job =
        quartzJobService.lambdaQuery().eq(QuartzJob::getJobClassName, jobClassName).one();
    if (CommonUtil.isNullOrEmpty(job)) {
      throw new KKException("定时任务不存在");
    }
    quartzJobService.resumeJob(job);
  }

  @Operation(summary = "分页列表")
  @PostMapping("/getPageList")
  public Page<QuartzJobListVO> getPageList(@RequestBody @Valid QuartzJobPageDTO pageDTO) {
    Page<QuartzJob> page = quartzJobService.getPageList(pageDTO);
    Page<QuartzJobListVO> buildResource = SystemUtil.buildResource(page, QuartzJobListVO.class);
    dictService.transfer(buildResource);
    return buildResource;
  }
}
